/*
 * @(#)TestsetAction.java
 *
 *
 *
 * ver 1.0 Sep 6, 2007 ggranum
 */
package org.testfire.realm.view.json.action;

import java.util.List;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.testfire.realm.control.auth.user.UserDBAO;
import org.testfire.realm.control.exception.UpdateException;
import org.testfire.realm.control.testfire.TestFireDBAO;
import org.testfire.realm.control.testfire.queue.QueueBean;
import org.testfire.realm.control.user.UserBean;
import org.testfire.realm.model.entities.User;
import org.testfire.realm.model.entities.testfire.AgentEntity;
import org.testfire.realm.model.entities.testfire.CrontaskEntity;
import org.testfire.realm.model.entities.testfire.TestRunnerQueueEntity;
import org.testfire.realm.model.entities.testfire.TestsetEntity;
import org.testfire.realm.view.json.translator.AgentTranslator;
import org.testfire.realm.view.json.translator.QueueTranslator;
import org.testfire.realm.view.json.translator.TestsetTranslator;

// eof: TestsetAction.java

public class QueueAction implements JsonAction<String>
{

    @PersistenceContext(unitName = "testfire")
    EntityManager em;

    @Resource
    private UserTransaction utx;

    TestFireDBAO testfireDBAO;

    QueueBean queueBean;

    TestsetTranslator testsetTranslator;

    AgentTranslator agentTranslator;

    QueueTranslator queueTranslator;

    UserBean userBean;

    UserDBAO userDBAO;

    Logger log = Logger.getLogger( QueueAction.class );

    public String perform( String[] argumentKeys, String... args )
        throws UpdateException
    {
        try
        {

            try
            {
                utx.begin();
                if ( args[0].equals( "add" ) )
                {
                    // 'add' is adding an existing row:
                    TestsetEntity translatedObj = testsetTranslator.toObject( args[1] );
                    TestsetEntity testset = em.find( TestsetEntity.class, translatedObj.getId() );
                    testset = em.merge( testset );
                    testsetTranslator.copyValues( testset, translatedObj );
                    TestRunnerQueueEntity queue = this.queueBean.getQueue( Integer.valueOf( args[2] ) );
                    queue.getTestsets().add( testset );
                }
                else if ( args[0].equals( "remove" ) )
                {
                    // 'remove' is removign a row from the queue.
                    int id = Integer.valueOf( args[1] );
                    TestRunnerQueueEntity queue = this.queueBean.getQueue( Integer.valueOf( args[2] ) );
                    List<TestsetEntity> testsets = queue.getTestsets();

                    for ( int i = 0; i < testsets.size(); i++ )
                    {
                        TestsetEntity ts = testsets.get( i );
                        if ( ts.getId() == id )
                        {
                            testsets.remove( i );
                            break;
                        }
                    }
                    this.testfireDBAO.merge( queue );
                }
                else if ( args[0].equals( "addAgent" ) )
                {
                    // 'add' is adding an existing row:
                    AgentEntity translatedObj = agentTranslator.toObject( args[1] );
                    AgentEntity agent = em.merge( em.find( AgentEntity.class, translatedObj.getId() ) );
                    utx.commit();
                    agentTranslator.copyValues( agent, translatedObj );
                    utx.begin();
                    TestRunnerQueueEntity queue = this.queueBean.getQueue( Integer.valueOf( args[2] ) );
                    queue = em.merge( queue );
                    utx.commit();
                    utx.begin();
                    queue.getAgents().add( agent );
                    em.merge( queue );
                }
                else if ( args[0].equals( "removeAgent" ) )
                {
                    // 'add' is adding an existing row:
                    AgentEntity agent = em.merge(em.find( AgentEntity.class, Integer.valueOf(args[1]) ));
                    TestRunnerQueueEntity queue = this.queueBean.getQueue( Integer.valueOf( args[2] ) );
                    queue = em.merge( queue );
                    queue.getAgents().remove( agent );
                }
                else if ( args[0].equals( "commit" ) )
                {
                    TestRunnerQueueEntity translatedObj = queueTranslator.toObject( args[1] );
                    TestRunnerQueueEntity queue = em.find( TestRunnerQueueEntity.class, translatedObj.getId() );
                    queueTranslator.copyValues( queue, translatedObj );
                }
                else if ( args[0].equals( "new" ) )
                {

                    User u = userBean.getUser();
                    String userName = u.getName();
                    CrontaskEntity cte = new CrontaskEntity();
                    cte.setCronString( "* 20 * * 1,2,3,4,5" );
                    cte.setName( "--" );
                    cte.setDescription( "--" );

                    TestRunnerQueueEntity queue = new TestRunnerQueueEntity();
                    queue.setCronTask( cte );
                    queue.setName( "name" );
                    queue.setDescription( userName + "'s Personal Queue. Runs every weekday at 20:00 hours." );
                    queue.setUser( u.getId() );
                    testfireDBAO.persist( queue );
                }
                em.flush();                
                utx.commit();
                return "success";
            }
            catch ( JSONException e )
            {
                throw new RuntimeException( e );
            }
        }
        catch ( Exception ex )
        {
            log.error( "Could not commit changes to TestRunnerQueue entity.", ex );
            try
            {
                if ( utx.getStatus() == Status.STATUS_ACTIVE )
                {
                    utx.rollback();
                }
            }
            catch ( Exception ex2 )
            {
                log.error("Could not roll back changes to TestRunnerQueueEntity.", ex2);
            }
        }
        return "-- error --";
    }

    public void setTestfireDBAO( TestFireDBAO testfireDBAO )
    {
        this.testfireDBAO = testfireDBAO;
    }

    public void setUserBean( UserBean userBean )
    {
        this.userBean = userBean;
    }

    public void setQueueBean( QueueBean queueBean )
    {
        this.queueBean = queueBean;
    }

    public void setTestsetTranslator( TestsetTranslator testsetTranslator )
    {
        this.testsetTranslator = testsetTranslator;
    }

    public void setQueueTranslator( QueueTranslator queueTranslator )
    {
        this.queueTranslator = queueTranslator;
    }

    public void setAgentTranslator( AgentTranslator agentTranslator )
    {
        this.agentTranslator = agentTranslator;
    }
}